#include "straightline/slp.h"

#include <iostream>

//本文件提供所有函数定义

namespace A {
/*----------------------------------------------------------------------------------*/
//关于组合语句
int A::CompoundStm::MaxArgs() const {
  // TODO: put your code here (lab1).
  int args1 = stm1->MaxArgs();
  int args2 = stm2->MaxArgs();
  return (args1 > args2) ? args1 : args2;
}

Table *A::CompoundStm::Interp(Table *t) const {
  // TODO: put your code here (lab1).
  Table* t1 = stm1->Interp(t);
  return stm2->Interp(t1);
}

//关于赋值语句
int A::AssignStm::MaxArgs() const {
  // TODO: put your code here (lab1).
  return exp->MaxArgs();
}

Table *A::AssignStm::Interp(Table *t) const {
  // TODO: put your code here (lab1).
  IntAndTable* iandt = exp->InterpExp(t);
  return iandt->t->Update(id,iandt->i);
}

//关于打印语句
int A::PrintStm::MaxArgs() const {
  // TODO: put your code here (lab1).
  std::list<Exp*> all_exp;
  exps->IntegrityExpList(all_exp);
  int maxargs = all_exp.size();
  for(auto& exp:all_exp)
  {
    int tmp = exp->MaxArgs();
    if(tmp > maxargs) maxargs = tmp;
  }
  return maxargs;
}

Table *A::PrintStm::Interp(Table *t) const {
  // TODO: put your code here (lab1).
  Table* tmp = t;
  std::list<Exp*> all_exp;
  exps->IntegrityExpList(all_exp);
  for(auto& exp:all_exp)
  {
    IntAndTable* iandt = exp->InterpExp(tmp);
    tmp = iandt->t;
    std::cout << iandt->i << ' ';
  }
  std::cout << std::endl;
  return tmp;
}
/*----------------------------------------------------------------------------------*/
//关于标识符表达式
int IdExp::MaxArgs() const {
  return 0; // should be 0 for none print stm testcase
}

IntAndTable *IdExp::InterpExp(Table *t) const {
  return new IntAndTable(t->Lookup(id), t);
}

//关于数字表达式
int NumExp::MaxArgs() const {
  return 0; // should be 0 for none print stm testcase
}

IntAndTable *NumExp::InterpExp(Table *t) const {
  return new IntAndTable(num, t);
}

//关于操作符表达式
int OpExp::MaxArgs() const {
  int args1 = left->MaxArgs();
  int args2 = right->MaxArgs();
  // std::cout << args1 << " " << args2 << std::endl;
  return args1 > args2 ? args1 : args2;
}

IntAndTable *OpExp::InterpExp(Table *t) const {
  IntAndTable *expValue1 = left->InterpExp(t);
  IntAndTable *expValue2 = right->InterpExp(t);
  switch (oper) {
  case PLUS:
    return new IntAndTable(expValue1->i + expValue2->i, expValue2->t);
  case MINUS:
    return new IntAndTable(expValue1->i - expValue2->i, expValue2->t);
  case TIMES:
    return new IntAndTable(expValue1->i * expValue2->i, expValue2->t);
  case DIV:
    return new IntAndTable(expValue1->i / expValue2->i, expValue2->t);
  default: // add default for robustness
    break;
  }
  return nullptr;
}

//关于序列表达式
int EseqExp::MaxArgs() const {
  int args1 = stm->MaxArgs();
  int args2 = exp->MaxArgs();
  return args1 > args2 ? args1 : args2;
}

IntAndTable *EseqExp::InterpExp(Table *t) const {
  return exp->InterpExp(stm->Interp(t));
}
/*----------------------------------------------------------------------------------*/
//关于对偶表达式列表
int PairExpList::MaxArgs() const {
  int num1 = exp->MaxArgs();
  int num2 = tail->MaxArgs();
  return num1 > num2 ? num1 : num2;
}

int PairExpList::NumExps() const { return 1 + tail->NumExps(); }

IntAndTable *PairExpList::Interp(Table *t) const {
  IntAndTable *temp_table = exp->InterpExp(t);
  printf("%d ", temp_table->i);
  return tail->Interp(temp_table->t);
}

void PairExpList::IntegrityExpList(std::list<Exp*>& exp_list)const{
   tail->IntegrityExpList(exp_list);//递归对后面的表达式列表使用该方法
   exp_list.push_front(exp);//把对偶列表里面的表达式放在后面的列表前面，组成完整的表达式列表
 }

//关于终止表达式列表
int LastExpList::MaxArgs() const { return exp->MaxArgs(); }

int LastExpList::NumExps() const { return 1; }

IntAndTable *LastExpList::Interp(Table *t) const {
  // return exp->InterpExp(t);
  IntAndTable *int_and_table = exp->InterpExp(t);
  printf("%d\n", int_and_table->i);
  return int_and_table;
}

void LastExpList::IntegrityExpList(std::list<Exp*>& exp_list) const {
   exp_list.push_back(exp);//在传入链表后端插入终表达式
}

/*----------------------------------------------------------------------------------*/
//关于表的查找与更新
int Table::Lookup(const std::string &key) const {
  if (id == key) {
    return value;
  } else if (tail != nullptr) {
    return tail->Lookup(key);
  } else {
    assert(false);
  }
}

Table *Table::Update(const std::string &key, int val) const {
  return new Table(key, val, this);
}
} // end of namespace A
